﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;


namespace mirror
{
    public class cLocalFx : cLocalFxRenderable
    {
        Effect mFx;
        Texture2D mTexture;
        bool mRendered;
        Matrix mTrans;

        float mCurrentTime;

        bool mAlive;
        
        protected LocalFx.Settings mSettings;

        public cLocalFx()
        {
            mRendered = false;
            mAlive = true;
        }

        public virtual void LoadContent(ContentManager content, string settingsName)
        {
            mSettings = content.Load<LocalFx.Settings>(settingsName);
            mFx = content.Load<Effect>(mSettings.EffectFile);
            mTexture = content.Load<Texture2D>(mSettings.Texture);
        }
        
        public void Start(Matrix trans, float duration)
        {
            mSettings.Duration = duration;
            Start(trans);
        }

        public void Start(Matrix trans)
        {
            mTrans = trans;
            mCurrentTime = 0.0f;
            cRenderManager.Instance.AddLocalFx(this);
        }

        public void Stop()
        {
            
            SetAlive(false);
        }

        public override bool Alive() { return mAlive; }
        public void SetAlive(bool val) { mAlive = val; }

        public override void Update(GameTime gametime)
        {
            mCurrentTime += (float)gametime.ElapsedGameTime.TotalSeconds;
            if ((mCurrentTime > mSettings.Duration) && (mSettings.Duration > 0.0f))
                Stop();
            if ((mSettings.Duration < 0.0f) && mRendered)
                Stop();

            mFx.Parameters["World"].SetValue(mTrans);
            mFx.Parameters["View"].SetValue(Camera.Instance.ViewMatrix);
            mFx.Parameters["Projection"].SetValue(Camera.Instance.ProjectionMatrix);
            mFx.Parameters["Texture"].SetValue(mTexture);
        }

        public override void Render()
        {
            mRendered = true;
            // Update all stuff you want
            cRenderManager.Instance.RenderQuad(mFx,mSettings.NumQuads);
        }
    }
    
    public class cLaserFx : cLocalFxRenderable
    {
        Effect mFx;
        Matrix mTrans;

        bool mAlive;
        float mMinLength;
        float mSpeed;
        float mThickness;
        float mLightIntensity;
        float mCurrentTime;
        Color mEdgeColor;
        Color mInteriorColor;
        float mDuration;

        public cLaserFx(float minLength,
                        float speed,
                        float thickness,
                        float intensity,
                        Color edgeColor,
                        Color interiorColor)
        {
            mAlive = false;
            mMinLength = minLength;
            mSpeed = speed;
            mThickness = thickness;
            mLightIntensity = intensity;
            mEdgeColor = edgeColor;
            mInteriorColor = interiorColor;

            ContentManager content = cRenderManager.Instance.Content();
            GraphicsDevice device = cRenderManager.Instance.Device();
            mFx = content.Load<Effect>("localfx/IronLaser").Clone();
            //mTex = content.Load<Texture2D>("LaserTexture");

            Vector4 edgeCol = mEdgeColor.ToVector4();
            edgeCol.W = 0.0f;

            mFx.Parameters["minLength"].SetValue(mMinLength);
            mFx.Parameters["speed"].SetValue(mSpeed);
            mFx.Parameters["thickness"].SetValue(mThickness);
            mFx.Parameters["intensity"].SetValue(mLightIntensity);
            mFx.Parameters["edgeColor"].SetValue(edgeCol);
            mFx.Parameters["interiorColor"].SetValue(mInteriorColor.ToVector4());
        }

        public void Update(float dt)
        {
            mFx.Parameters["age"].SetValue(mCurrentTime);
            mFx.Parameters["View"].SetValue(Camera.Instance.ViewMatrix);
            mFx.Parameters["Projection"].SetValue(Camera.Instance.ProjectionMatrix);

            if (mDuration < mCurrentTime)
                Stop();

            mCurrentTime += dt;
        }

        public override void Render()
        {
            // Update all stuff you want
            GraphicsDevice device = cRenderManager.Instance.Device();

            device.BlendState = BlendState.NonPremultiplied;

            //device.RenderState.CullMode = CullMode.CullClockwiseFace;
           // TODO: Set states
            cRenderManager.Instance.RenderQuad(mFx, 1);
            //device.RenderState.CullMode = CullMode.CullCounterClockwiseFace;
        }

        public void Start(Matrix trans, float offsetX, float offsetZ, float duration)
        {
            mAlive = true;
            mTrans = trans;
            mCurrentTime = 0.0f;
            mDuration = duration;
            mFx.Parameters["World"].SetValue(mTrans);
            mFx.Parameters["LaserOffsetX"].SetValue(offsetX);
            mFx.Parameters["LaserOffsetZ"].SetValue(offsetZ);
            cRenderManager.Instance.AddLocalFx(this);
        }

        public void Stop()
        {
            SetAlive(false);
        }
        public override bool Alive() { return mAlive; }
        public void SetAlive(bool val) { mAlive = val; }
        public Matrix GetTransform() { return mTrans; }
    }
}
